package com.changgou.order.service.impl;

import com.changgou.entity.Result;
import com.changgou.feign.SkuFeign;
import com.changgou.feign.WxPayFeign;
import com.changgou.order.dao.OrderConfigMapper;
import com.changgou.order.dao.OrderItemMapper;
import com.changgou.order.dao.OrderLogMapper;
import com.changgou.order.dao.OrderMapper;
import com.changgou.order.service.CartService;
import com.changgou.order.service.OrderItemService;
import com.changgou.order.service.OrderService;
import com.changgou.pojo.Order;
import com.changgou.pojo.OrderConfig;
import com.changgou.pojo.OrderItem;
import com.changgou.pojo.OrderLog;
import com.changgou.util.IdWorker;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.time.LocalDate;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/** 
* @Author: 少迪
* @Date: Created in 2019-08-09 11:31
* @Description:  
* @Version: 1.0
*/ 

@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private OrderItemMapper orderItemMapper;

    @Autowired
    private CartService cartService;

    @Autowired
    private OrderItemService orderItemService;

    @Autowired
    private IdWorker idWorker;

    @Autowired
    private SkuFeign skuFeign;

    @Autowired
    private OrderLogMapper orderLogMapper;

    @Autowired
    private WxPayFeign wxPayFeign;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private OrderConfigMapper orderConfigMapper;

    /**
     * 查询全部列表
     * @return
     */
    @Override
    public List<Order> findAll() {
        return orderMapper.selectAll();
    }

    /**
     * 根据ID查询
     * @param id
     * @return
     */
    @Override
    public Order findById(String id){
        return  orderMapper.selectByPrimaryKey(id);
    }


    /**
     * 增加
     * @param order
     */
    @Override
    @GlobalTransactional(name = "order_add")
    public Order add(Order order){
        //1.刷新购物车  代码略

        //2.获取购物车并进行校验
        Map cart = cartService.findCart( order.getUsername() );
        //支付金额
        Integer payMoney = (Integer) cart.get( "payMoney" );
        if(payMoney<=0){
            throw new RuntimeException( "当前无订单记录" );
        }

        //扣减库存
        List<Map<String,Object>> cartList = (List<Map<String,Object>>)cart.get( "cartList" );
        Map stockMap=new HashMap(50);
        for(Map<String,Object> map:cartList){
            //是否选中
            boolean checked= (boolean)map.get( "checked" );
            if(checked){
                OrderItem orderItem = (OrderItem)map.get( "item" );
                stockMap.put( orderItem.getSkuId(),orderItem.getNum()  );
            }
        }
        Result result = skuFeign.deductionStock( stockMap );
        if(!result.isFlag()){
            throw  new RuntimeException( "库存扣减失败" );
        }

        //3.保存订单主表
        //订单号
        String orderId = idWorker.nextId()+"";
        order.setId(orderId  );
        order.setCreateTime( new Date(  ) );
        order.setUpdateTime( new Date(  ) );

        order.setTotalNum(  (Integer) cart.get( "num" )  );
        order.setTotalMoney( (Integer) cart.get( "money" )   );
        order.setPreMoney(   (Integer) cart.get( "preMoney" )  );
        order.setPayMoney(  payMoney );
        orderMapper.insertSelective( order );
        //4.保存订单明细表

        for( Map<String,Object> map: cartList ){
            //是否选中
            boolean checked= (boolean)map.get( "checked" );
            if(checked){
                OrderItem orderItem = (OrderItem)map.get( "item" );
                orderItem.setId( idWorker.nextId()+"" );
                orderItem.setOrderId( orderId );
                orderItemMapper.insertSelective( orderItem );
            }
        }
//        int a = 1/0;
        //5.删除购物车中选中的记录
        cartService.deleteChecked( order.getUsername() );

        //6.发送到mq  延迟消息  (60分钟过期自动关闭)
        rabbitTemplate.convertAndSend( "","queue.ordercreate", orderId);
        return order;
    }


    /**
     * 修改
     * @param order
     */
    @Override
    public void update(Order order){
        orderMapper.updateByPrimaryKey(order);
    }

    /**
     * 删除
     * @param id
     */
    @Override
    public void delete(String id){
        orderMapper.deleteByPrimaryKey(id);
    }


    /**
     * 条件查询
     * @param searchMap
     * @return
     */
    @Override
    public List<Order> findList(Map<String, Object> searchMap){
        Example example = createExample(searchMap);
        return orderMapper.selectByExample(example);
    }

    /**
     * 分页查询
     * @param page
     * @param size
     * @return
     */
    @Override
    public Page<Order> findPage(int page, int size){
        PageHelper.startPage(page,size);
        return (Page<Order>)orderMapper.selectAll();
    }

    /**
     * 条件+分页查询
     * @param searchMap 查询条件
     * @param page 页码
     * @param size 页大小
     * @return 分页结果
     */
    @Override
    public Page<Order> findPage(Map<String,Object> searchMap, int page, int size){
        PageHelper.startPage(page,size);
        Example example = createExample(searchMap);
        Page<Order> orders = (Page<Order>) orderMapper.selectByExample(example);
        for (Order order : orders) {
            List<OrderItem> orderItems = orderItemService.findByOrderId(order.getId());
            order.setOrderItems(orderItems);
        }
        return orders;
    }

    /**
     * 批量发货
     *
     * @param orderList
     */
    @Override
    @Transactional
    public void batchSend(List<Order> orderList) {
        //1.做非空校验
        for(Order order:orderList){
            if(order.getId()==null){
                throw  new RuntimeException( "订单号不能为空" );
            }
            if(order.getShippingName()==null){
                throw  new RuntimeException( "物流公司不能为空" );
            }
            if(order.getShippingCode()==null){
                throw  new RuntimeException( "运单号不能为空" );
            }
        }

        //2.数据校验
        for(Order order:orderList){
            Order order1 = orderMapper.selectByPrimaryKey( order.getId() );
            if(order1==null){
                throw  new RuntimeException( "订单不存在" );
            }
            if(!"1".equals( order1.getOrderStatus() )){
                throw  new RuntimeException( "订单状态异常" );
            }
            if(!"1".equals( order1.getPayStatus() )){
                throw  new RuntimeException( "付款状态异常" );
            }
        }

        //3.批量处理
        for(Order order:orderList){
            //已发货
            order.setOrderStatus( "2" );
            //已发货  0:未发货  1：已发货
            order.setConsignStatus( "1" );
            //发货时间
            order.setConsignTime( new Date(  ) );
            order.setUpdateTime( new Date(  ) );
            orderMapper.updateByPrimaryKeySelective( order );

            //记录日志
            OrderLog orderLog=new OrderLog();
            orderLog.setOrderStatus( "2" );
            orderLog.setConsignStatus( "1" );
            //system   admin   user
            orderLog.setOperater( "admin" );
            orderLog.setOperateTime( new Date(  ) );
            orderLog.setOrderId( order.getId() );
            orderLog.setId(  idWorker.nextId()+"" );
            orderLogMapper.insertSelective( orderLog );
        }
    }

    /**
     * 自动确认收货
     */
    @Override
    @Transactional
    public void autoTake() {
        //查询订单配置表中  自动确认收货的时间
        OrderConfig orderConfig = orderConfigMapper.selectByPrimaryKey( 1 );

        //查询超时未确认收货的订单
        //15天
        Integer takeDays = orderConfig.getTakeTimeout();
        //获取当前日期
        LocalDate now=LocalDate.now();
        //15天之前的时间
        LocalDate date = now.plusDays( -takeDays );

        Example example=new Example( Order.class );
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo( "orderStatus","2" );
        criteria.andLessThan("consignTime", date );
        List<Order> orders = orderMapper.selectByExample( example );

        //批量收货处理
        for(Order order:orders){
            System.out.println("自动收货:"+order.getId());
            //改变订单状态
            take(order.getId(),"system");
        }
    }

    /**
     * 确认收货
     *
     * @param orderId
     * @param operator
     */
    @Override
    @Transactional
    public void take(String orderId, String operator) {
        //1.查询订单，校验
        Order order = orderMapper.selectByPrimaryKey( orderId );
        if(order==null){
            throw new RuntimeException( "订单不存在" );
        }
        if(!"2".equals( order.getOrderStatus() ) ){
            throw new RuntimeException( "订单状态异常" );
        }
        if(!"1".equals( order.getConsignStatus()) ){
            throw new RuntimeException( "发货状态异常" );
        }
        //更改订单状态
        //已确认收货
        order.setOrderStatus( "3" );
        order.setUpdateTime( new Date(  ) );
        //结束时间
        order.setEndTime( new Date(  ) );
        orderMapper.updateByPrimaryKeySelective( order );

        //记录订单日志
        OrderLog orderLog=new OrderLog();
        orderLog.setOrderStatus( "3" );
        //system   admin   user
        orderLog.setOperater( operator );
        orderLog.setOperateTime( new Date(  ) );
        orderLog.setOrderId( order.getId() );
        orderLog.setId(  idWorker.nextId()+"" );
        orderLogMapper.insertSelective( orderLog );
    }

    /**
     * 关闭订单逻辑
     *
     * @param orderId
     */
    @Override
    @GlobalTransactional
    public void closeOrder(String orderId) {
        //1.根据订单号查询订单，并进行校验
        Order order = orderMapper.selectByPrimaryKey( orderId );
        if(order==null){
            System.out.println("订单不存在");
            return ;
        }
        if(!"0".equals( order.getOrderStatus() )){
            System.out.println("订单已付款，无需关闭");
            return ;
        }

        //2.如果该订单未支付，查询微信订单，看是否真的未支付
        Map<String,String> wxpayMap = ( Map<String,String>)wxPayFeign.queryOrder( orderId ).getData();
        if(wxpayMap==null){
            return ;
        }

        //2.1 如果未支付  关闭订单处理逻辑
        if("NOTPAY".equals( wxpayMap.get( "trade_state" ) )){
            //2.1.1 修改订单状态为已关闭
            //0:未付款  1：已付款（未发货） 2：已发货  3:已收货  4：已关闭
            order.setOrderStatus( "4" );
            order.setUpdateTime( new Date(  ) );
            order.setCloseTime( new Date(  ) );
            orderMapper.updateByPrimaryKeySelective( order );

            //2.1.2 记录订单操作日志
            OrderLog orderLog=new OrderLog();
            orderLog.setOrderStatus( "4" );
            //system   admin   user
            orderLog.setOperater( "system" );
            orderLog.setOperateTime( new Date(  ) );
            orderLog.setOrderId( orderId );
            orderLog.setId(  idWorker.nextId()+"" );
            orderLogMapper.insertSelective( orderLog );
            //2.1.3 恢复库存数和销量数
            OrderItem orderItem0=new OrderItem();
            orderItem0.setOrderId( orderId );
            List<OrderItem> orderItemList = orderItemMapper.select( orderItem0 );
            Map stockMap=new HashMap( 30 );
            for( OrderItem orderItem :orderItemList){
                stockMap.put( orderItem.getSkuId(),-orderItem.getNum()  );
            }
            Result result = skuFeign.deductionStock( stockMap );
            if(!result.isFlag()){
                //做日志记录
            }
            //2.1.4 关闭微信订单
            wxPayFeign.closeOrder( orderId );
            System.out.println("关闭订单完成 ,订单号："+orderId);
        }

        //2.2 如果已支付
        if("SUCCESS".equals( wxpayMap.get( "trade_state" ) )){
            System.out.println("订单状态补偿 ,订单号："+orderId);
            //做订单状态补偿
            updateOrderStatus( orderId, wxpayMap.get( "transaction_id" )  );
        }
    }

    /**
     * 修改订单状态
     *
     * @param orderId       订单号
     * @param transactionId 微信交易流水号
     */
    @Override
    public void updateOrderStatus(String orderId, String transactionId) {
        //1.修改订单主表
        Order order = orderMapper.selectByPrimaryKey( orderId );
        if(order==null){
            return ;
        }
        if( !"0".equals( order.getOrderStatus() ) ){
            return;
        }
        //订单状态  0未付款，1 已付款  .......
        order.setOrderStatus( "1" );
        //付款状态
        order.setPayStatus( "1" );
        order.setTransactionId( transactionId );
        order.setPayTime( new Date(  ) );
        order.setUpdateTime( new Date(  ) );
        orderMapper.updateByPrimaryKeySelective( order );

        //2.记录订单日志
        OrderLog orderLog=new OrderLog();
        orderLog.setOrderStatus( "1" );
        orderLog.setPayStatus( "1" );
        //system   admin   user
        orderLog.setOperater( "system" );
        orderLog.setOperateTime( new Date(  ) );
        orderLog.setOrderId( orderId );
        orderLog.setId(  idWorker.nextId()+"" );

        orderLogMapper.insertSelective( orderLog );
    }

    /**
     * 构建查询对象
     * @param searchMap
     * @return
     */
    private Example createExample(Map<String, Object> searchMap){
        Example example=new Example(Order.class);
        Example.Criteria criteria = example.createCriteria();
        if(searchMap!=null){
            // 订单id
            if(searchMap.get("id")!=null && !"".equals(searchMap.get("id"))){
                criteria.andLike("id","%"+searchMap.get("id")+"%");
           	}
            // 支付类型，1、在线支付、0 货到付款
            if(searchMap.get("pay_type")!=null && !"".equals(searchMap.get("pay_type"))){
                criteria.andLike("pay_type","%"+searchMap.get("pay_type")+"%");
           	}
            // 物流名称
            if(searchMap.get("shipping_name")!=null && !"".equals(searchMap.get("shipping_name"))){
                criteria.andLike("shipping_name","%"+searchMap.get("shipping_name")+"%");
           	}
            // 物流单号
            if(searchMap.get("shipping_code")!=null && !"".equals(searchMap.get("shipping_code"))){
                criteria.andLike("shipping_code","%"+searchMap.get("shipping_code")+"%");
           	}
            // 用户名称
            if(searchMap.get("username")!=null && !"".equals(searchMap.get("username"))){
                criteria.andEqualTo("username",(String)searchMap.get("username"));
           	}
            // 买家留言
            if(searchMap.get("buyer_message")!=null && !"".equals(searchMap.get("buyer_message"))){
                criteria.andLike("buyer_message","%"+searchMap.get("buyer_message")+"%");
           	}
            // 是否评价
            if(searchMap.get("buyer_rate")!=null && !"".equals(searchMap.get("buyer_rate"))){
                criteria.andLike("buyer_rate","%"+searchMap.get("buyer_rate")+"%");
           	}
            // 收货人
            if(searchMap.get("receiver_contact")!=null && !"".equals(searchMap.get("receiver_contact"))){
                criteria.andLike("receiver_contact","%"+searchMap.get("receiver_contact")+"%");
           	}
            // 收货人手机
            if(searchMap.get("receiver_mobile")!=null && !"".equals(searchMap.get("receiver_mobile"))){
                criteria.andLike("receiver_mobile","%"+searchMap.get("receiver_mobile")+"%");
           	}
            // 收货人地址
            if(searchMap.get("receiver_address")!=null && !"".equals(searchMap.get("receiver_address"))){
                criteria.andLike("receiver_address","%"+searchMap.get("receiver_address")+"%");
           	}
            // 订单来源：1:web，2：app，3：微信公众号，4：微信小程序  5 H5手机页面
            if(searchMap.get("source_type")!=null && !"".equals(searchMap.get("source_type"))){
                criteria.andLike("source_type","%"+searchMap.get("source_type")+"%");
           	}
            // 交易流水号
            if(searchMap.get("transaction_id")!=null && !"".equals(searchMap.get("transaction_id"))){
                criteria.andLike("transaction_id","%"+searchMap.get("transaction_id")+"%");
           	}
            // 订单状态
            if(searchMap.get("order_status")!=null && !"".equals(searchMap.get("order_status"))){
                criteria.andLike("order_status","%"+searchMap.get("order_status")+"%");
           	}
            // 支付状态
            if(searchMap.get("pay_status")!=null && !"".equals(searchMap.get("pay_status"))){
                criteria.andLike("pay_status","%"+searchMap.get("pay_status")+"%");
           	}
            // 发货状态
            if(searchMap.get("consign_status")!=null && !"".equals(searchMap.get("consign_status"))){
                criteria.andLike("consign_status","%"+searchMap.get("consign_status")+"%");
           	}

            // 数量合计
            if(searchMap.get("totalNum")!=null ){
                criteria.andEqualTo("totalNum",searchMap.get("totalNum"));
            }
            // 金额合计
            if(searchMap.get("totalMoney")!=null ){
                criteria.andEqualTo("totalMoney",searchMap.get("totalMoney"));
            }
            // 优惠金额
            if(searchMap.get("preMoney")!=null ){
                criteria.andEqualTo("preMoney",searchMap.get("preMoney"));
            }
            // 邮费
            if(searchMap.get("postFee")!=null ){
                criteria.andEqualTo("postFee",searchMap.get("postFee"));
            }
            // 实付金额
            if(searchMap.get("payMoney")!=null ){
                criteria.andEqualTo("payMoney",searchMap.get("payMoney"));
            }

        }
        return example;
    }

}
